#ifndef __CC_BY_PACKET_H__
#define __CC_BY_PACKET_H__

#pragma once
////////////////////////////////////////////////////////////////////////////////
// PacketBase
////////////////////////////////////////////////////////////////////////////////
// STLͷ�ļ�����
#include <string>
#include <queue>
#include <vector>
#include <deque>
#include <list>
#include <iostream>
#include <map>
#include <arpa/inet.h> 
#include <string.h>
#include "cache.h"
#include "PacketBase.h"
#include "Protocol.h"
#include <google/protobuf/message.h>

extern const uint32 g_encodeflag;

using namespace std;
using namespace comm::sockcommu;

#define NAMESPACE_CC_BY_BEGIN namespace protol_cc_by{
#define NAMESPACE_CC_BY_END }

NAMESPACE_CC_BY_BEGIN




//#define LUA_CCPACKET_LEN 8192
#define  MAX_PACKET_LEN   (1024*31)  // 31KB
#define  PACKET_BUFFER_SIZE   (MAX_PACKET_LEN)
#define MAX_JD_EXTDATA_LEN   (128)

#define QE_DEFAULT_GAMEID	0x11
#define QE_DEFAULT_VERSION	0x01
#define DEFAULT_VERSION		0x01



class CCPackete :public CCPacketBase
{
public:
	CCPackete(void);
	virtual ~CCPackete(void);

	char *packet_buf(void);
	int packet_size(void);
	static int parse_protocol(const char* data);
	static int parse_head_len(int protocol);
	static bool check_head(const char* data);
	static int parse_packet_len(const char* data);

private:                                                                                                                                                                        
	CRawCache m_cache;
	int m_protocol;
	int m_nBufPos;  
    BYTE m_bIsEncrypted;
	void ParseExtData(void);
	void ParseJDExtData(void);
protected:
	bool _copy(const void *pInBuf, int nLen);
	void _begin(uint32 nCmdType, int proto_type);
	void _begin(unsigned int cmd, unsigned short dsttype, unsigned int dstid, unsigned short srctype, unsigned int srcid, unsigned int seq, int proto_type);
	void writePBAHead(unsigned int cmd, unsigned short dsttype = 0, unsigned int dstid = 0, unsigned short srctype = 0, unsigned int srcid = 0, unsigned int seq = 0, unsigned char ver =0);
public:
	int GetCmdType(void);
	int GetSubCmdType(void);
	char GetVersion(void);
	int GetBodyLength(void);
	int GetHeadLength(void);
	int GetContentLength(void);
	uint32 GetMsgType(void);
	USHORT GetDstType(void);
	uint32 GetDstSvid(void);
	USHORT GetSrcType(void);
	uint32 GetSrcSvid(void);
	void SetSrcSvid(unsigned int srcid);
	uint32 GetSeq(void);
	void SetSeq(uint32 seq);
	uint32 GetFlowId(void);
	uint32 GetModKey(void);
    uint32 Getbitflag(void);

	BYTE GetcbCheckCode(void);
	void WritecbCheckCode(BYTE nValue);
	bool IsWritecbCheckCode(void);
	void SetCheckCodeFlag(BYTE value);

	char* bodydata(void);
	unsigned int bodylen(void);
	bool parsePb(::google::protobuf::Message* pb);
	bool getPbData(std::string& data);
protected:
	void _end(bool encode = false);
	void _reset(void);
	bool _Read(char *pOut, int nLen);// ȡ��һ������
	void _readundo(int nLen);//������
	char*_readpoint(int nLen);
	bool _Write(const char *pIn, int nLen);// д��һ������
	bool _writezero(void);
};


class InputPacket : public CCPackete
{
public:
	InputPacket(){};
	virtual ~InputPacket(){};
public:
	typedef CCPackete base;
	int ReadInt(void);
	int64 ReadInt64(void);
	unsigned long ReadULong(void);
	short ReadShort(void);
	BYTE ReadByte(void);
	int ReadString(char *pOutString, int nMaxLen);
	char *ReadChar(void);
	std::string ReadString(void);
	int ReadBinary(char *pBuf, int nMaxLen);
	void Reset(void);
	bool Copy(const void *pInBuf, int nLen);

};


class OutputPacket : public CCPackete
{
public:
	OutputPacket();
	virtual ~OutputPacket();
public:
	typedef CCPackete base;
	bool WriteInt(int nValue);
	bool WriteInt64(int64 nValue);
	bool WriteByte(BYTE nValue);
	bool WriteShort(short nValue);
	bool WriteString(const char *pString);
	bool WriteString(const string &strDate);
	bool WriteBinary(const char *pBuf, int nLen);
	bool WriteBP(const char *pBuf, unsigned int nLen);
	bool Copy(const void *pInBuf, int nLen);
	void Begin(uint32 nCmd, int proto_type = DEFAULT_PROTOCOL);
	void Begin(unsigned int cmd, unsigned short dsttype, unsigned int dstid, unsigned short srctype = 0, unsigned int srcid = 0, unsigned int seq = 0, int proto_type = DEFAULT_PROTOCOL);
	void End(bool encode = false);
    //void WritecbCheckCode(BYTE nValue);
    //bool IsWritecbCheckCode(void);

};

typedef InputPacket		NETInputPacket;
typedef OutputPacket	NETOutputPacket;
typedef OutputPacket    NETMINOutputPacket;

NAMESPACE_CC_BY_END

#endif
